<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>黑客代码背景</title>
</head>

<body>
    <canvas id="c1" style="background-color: #000;"></canvas>
    <script>
        /** @type {HTMLCanvasElement} */
        const c1 = document.querySelector('#c1');
        const { clientWidth: width, clientHeight: height } = document.documentElement
        c1.width = width;
        c1.height = height;
        const ctx = c1.getContext('2d');
        const text = 'abcdefghijklmnopqrstuvwxyz'
        ctx.font = '14px 微软雅黑'
        const bl = 20;
        const startRates = {}
        const rates = {}
        const endRates = {}

        const textObj = {}

        const animate = () => {
            ctx.clearRect(0, 0, width, height)
            for (let i = 0; i < width; i += bl) {
                ctx.beginPath()
                const gradient = ctx.createLinearGradient(0, 0, 0, height);
                const s1 = 0.2 * Math.random()
                const s2 = 0.8 * Math.random()
                const step = 0.02 * Math.random()
                rates[i] = rates[i] || -s1
                startRates[i] = startRates[i] || s2
                endRates[i] = endRates[i] || 0
                /**
                 * 0  000
                 * 0.8  000
                 * 0.2  green
                 * 0 000
                 * 1 000
                 * **/
                gradient.addColorStop(0, '#000000')
                gradient.addColorStop(startRates[i] < 0 ? 0 : startRates[i], '#000000')
                gradient.addColorStop(rates[i] < 0 ? 0 : rates[i], 'green')
                gradient.addColorStop(endRates[i], '#000000')
                gradient.addColorStop(1, '#000000')
                if(i==120){
                    console.log(startRates[i],rates[i] ,endRates[i])
                }
                ctx.fillStyle = gradient;
                for (let j = 0; j < height; j += bl) {
                    textObj[`${i}-${j}`] = textObj[`${i}-${j}`] || text[parseInt(Math.random() * text.length)]
                    ctx.fillText(textObj[`${i}-${j}`], i, j)

                }
                rates[i] += step
                startRates[i] += step
                endRates[i] += step
                if (startRates[i] > 1) {
                    startRates[i] = -s2
                }
                if (rates[i] > 1) {
                    if (startRates[i] === -s2) {
                        rates[i] = -s1
                    }
                    else {
                        rates[i] = 1
                    }
                }
                if (endRates[i] > 1) {
                    if (startRates[i] === -s2 && rates[i] === -s1) {
                        endRates[i] = step
                    } else {
                        endRates[i] = 1
                    }

                }

            }
            //console.log(textObj)
            requestAnimationFrame(animate)
        }

        animate()
    </script>
</body>

</html>